package com.neusoft.elmboot.po.wallet;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.neusoft.elmboot.exception.exceptions.BaseException;
import com.neusoft.elmboot.exception.exceptions.IllegalAmountException;
import com.neusoft.elmboot.util.WalletUtils;
import com.neusoft.elmboot.util.response.ResultBody;
import lombok.Getter;
import lombok.NoArgsConstructor;
import io.swagger.v3.oas.annotations.Operation;
import lombok.Setter;
import org.springframework.transaction.annotation.Transactional;

import javax.naming.InsufficientResourcesException;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 由于是基于充血模型，我们在实体类中实现部分基本功能
 * 如支付，充值，冻结，解冻
 * 关于更复杂的功能，如充值返利等，在service中实现
 */

@Getter
@NoArgsConstructor
@Transactional(rollbackFor = Exception.class)
@TableName(value = "virtualwallet")
public class VirtualWallet implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 由于之前一直用手机号当主键，这里就偷懒沿用了
     */
    @TableId
    private String id;

    /**
     * 是否是VIP用户
     */
    @TableField(value = "is_vip")
    private Boolean isVIP = false;

    /**
     * 支付密码
     */
    private String payPwd;

    /**
     * 余额
     */
    private BigDecimal balance = BigDecimal.ZERO;

    /**
     * 是否允许透支
     */
    private Boolean isAllowedOverdraft = false;

    /**
     * 透支额度
     *（个人感觉这个功能有点抽象，商家怎么可能这么好心
     */
    private BigDecimal overdraftAmount = BigDecimal.ZERO;

    /**
     * 当前透支金额
     * 当一回奸商，这个字段包括利息，利滚利
     */
    @Setter
    private BigDecimal currentOverdraftAmount = BigDecimal.ZERO;

    /**
     * 冻结额度
     */
    private BigDecimal frozenAmount = BigDecimal.ZERO;

    private LocalDateTime createTime;


    public VirtualWallet(String id, String payPwd){
        this.id = id;
        this.payPwd = payPwd;
        this.createTime = LocalDateTime.now();
    }

    @Operation(summary = "获取全部可支配金额")
    public BigDecimal getAvailableBalance(){
        BigDecimal totalAvailableBalance=this.balance;
        if(isAllowedOverdraft) {
            totalAvailableBalance = totalAvailableBalance.add(this.overdraftAmount).subtract(currentOverdraftAmount);
        }
        return totalAvailableBalance;
    }

    @Operation(summary = "支付")
    public void debit(BigDecimal amount) throws BaseException{
        BigDecimal totalAvailableBalance = getAvailableBalance();
        if (amount.compareTo(BigDecimal.ZERO)<0){
            throw new IllegalAmountException("传入金额有误");
        }
        if(totalAvailableBalance.compareTo(amount) < 0){
            throw new IllegalAmountException("余额不足");
        }
        this.balance=this.balance.subtract(amount);
        if (this.balance.compareTo(BigDecimal.ZERO) < 0) {
            this.currentOverdraftAmount = this.currentOverdraftAmount.subtract(this.balance);
            if (this.currentOverdraftAmount.compareTo(this.overdraftAmount) >= 0) {
                closeOverdraft();
            }
            this.balance = BigDecimal.ZERO;
        }
    }

    @Operation(summary = "还款")
    public void repay(BigDecimal amount) throws BaseException {
        if (this.currentOverdraftAmount.compareTo(amount) > 0) {
            this.currentOverdraftAmount = this.currentOverdraftAmount.subtract(amount);
        } else if (this.currentOverdraftAmount.compareTo(amount) == 0){
            this.currentOverdraftAmount = BigDecimal.ZERO;
            if (this.isVIP) {
                openOverdraft();
            }
        } else {
            throw new IllegalAmountException("超出还款金额");
        }
    }

    @Operation(summary = "充值")
    public void credit(BigDecimal amount) throws BaseException{
        if (amount.compareTo(BigDecimal.ZERO) < 0){
            throw new IllegalAmountException("传入金额有误");
        }
        this.balance = this.balance.add(amount);
    }

    @Operation(summary = "冻结")
    public void freeze(BigDecimal amount) throws BaseException{
        if(amount.compareTo(BigDecimal.ZERO) < 0){
            throw new IllegalAmountException("传入金额有误");
        }
        this.frozenAmount=this.frozenAmount.add(amount);
    }

    @Operation(summary = "解冻")
    public void unfreeze(BigDecimal amount) throws BaseException{
        if((amount.compareTo(BigDecimal.ZERO) < 0) || (this.frozenAmount.compareTo(amount) < 0)){
            throw new IllegalAmountException("传入金额有误");
        }
        this.frozenAmount=this.frozenAmount.subtract(amount);
    }

    @Operation(summary = "允许透支")
    public void openOverdraft(){
        this.isAllowedOverdraft=true;
    }

    @Operation(summary = "禁止透支")
    public void closeOverdraft(){
        this.isAllowedOverdraft=false;
    }

    @Operation(summary = "增加透支上限")
    public void increaseOverdraftAmount(BigDecimal amount) throws BaseException{
        if(amount.compareTo(BigDecimal.ZERO)<0){
            throw new IllegalAmountException("传入金额有误");
        }
        this.overdraftAmount=this.overdraftAmount.add(amount);
    }

    @Operation(summary = "减少透支上限")
    public void decreaseOverdraftAmount(BigDecimal amount)throws BaseException{
        if((amount.compareTo(BigDecimal.ZERO)<0)||(this.overdraftAmount.compareTo(amount)<0)){
            throw new IllegalAmountException("传入金额有误");
        }
        this.overdraftAmount=this.overdraftAmount.subtract(amount);
    }

    public void hidePwd(){
        this.payPwd = "unknown";
    }

}
